iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
Software Development

C++ 實務基礎經驗系列 第 24

併發相關 非同步

  • 分享至 

  • xImage
  •  

併發相關 非同步

今天接著來介紹C++中幾個非同步函式

async

async能讓我們用非同步的方式去調用函數,而非同步調用中也有兩種模式,參考下面例子

#include <iostream>
#include <thread>
#include <future>
#include <chrono>

using namespace std;

int CalcNum ()
{
    cout << "calculatng!" << endl;
    return 20;
}

int main(int argc, char const *argv[])
{
    // future會是async的回傳,launch::async非同步策略會馬上執行
    auto future = async(launch::async, CalcNum);

    cout << "hello async " << endl;
    this_thread::sleep_for(chrono::seconds(1));
    cout << "answer is " << future.get() << endl;

    // launch::deferred則是延遲到future變數執行wait或get才會執行
    auto future2 = async(launch::deferred, CalcNum);

    cout << "hello deferred " << endl;
    this_thread::sleep_for(chrono::seconds(1));
    cout << "answer is " << future2.get() << endl;

    return 0;
}

promise

在多線程間如果要進行數據同步或通信,promisefuture是一種能單向傳遞數據的方式,參考下面例子

int main(int argc, char const *argv[])
{
    promise<int> pAnswer;

    // 傳遞數據的子線程
    auto t1 = thread([&pAnswer]
    {
        cout << "thread begin\n";
        this_thread::sleep_for(chrono::seconds(1));
        pAnswer.set_value(100);
        cout << "thread end\n";
    });

    // 主線程等數據
    cout << pAnswer.get_future().get() << endl;
    t1.join();

    return 0;
}

shared_future

剛剛上面的future如果get一次之後,再調用就有問題,而shared_futre的get可以一直調用,同時也能讓多個線程共享一個future,參考下面例子

int main(int argc, char const *argv[])
{
    auto promise = std::promise<int>();
    auto shared_fu = shared_future<int>(promise.get_future());

    auto t2 = thread([&promise]
    {
        cout << "thread 2 begin\n";
        this_thread::sleep_for(chrono::seconds(2));
        promise.set_value(100);
        cout << "thread 2 end\n";
    });

    auto t3 = thread([shared_fu]
    {
        cout << "thread 3 begin\n";
        // 若promise尚未set_value就會阻塞
        auto value = shared_fu.get();
        cout << "thread 3 get value " << value << endl;
        cout << "thread 3 end\n";
    });

    auto value = shared_fu.get();
    cout << "main get value " << value << endl;

    t2.join();
    t3.join();

    return 0;
}

packaged_task

packaged_task能讓我們再線程之間傳遞可調用的函數,參考下面例子

int add(int a, int b)
{
    return a + b;
}

int main(int argc, char const *argv[])
{
    packaged_task<int(int, int)> task(add);
    future<int> result = task.get_future();

    thread t4(move(task), 10, 20);
    cout << "result is " << result.get() << endl;

    t4.join();

    return 0;
}

參考

C++ 併發處理實戰


上一篇
併發相關 讀寫鎖
下一篇
併發相關 條件變數
系列文
C++ 實務基礎經驗25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言